package com.ljf.common.domain.validator;

import com.ljf.common.domain.repository.IBasisRepository;
import com.ljf.common.dto.query.PageParam;
import com.ljf.common.enums.ActivationEnum;
import com.ljf.common.exception.ServiceException;
import com.ljf.common.model.BasisModel;
import com.ljf.common.utils.CollectionUtil;
import com.ljf.common.utils.EnumUtil;
import org.springframework.context.ApplicationContext;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

/**
 * 基础业务校验
 *
 * @author LJF
 * @since 2024-02-09
 */
public class BasisValidator<Q extends PageParam, A extends Serializable, V extends Serializable, M extends BasisModel, R extends IBasisRepository<Q, V, M>> extends NoDbBasisValidator {

    protected static final Integer TIP_MAX_SIZE = 10;

    @Resource
    private ApplicationContext applicationContext;

    protected R repository;

    private Class<R> repositoryClass;

    /**
     * 分页查询接口 业务校验
     *
     * @param query
     * @throws ServiceException
     */
    public void checkQuery(Q query) throws ServiceException {
        if (query == null) {
            throw new ServiceException("基础业务校验异常:空指针");
        }
        if (query.getCurrent() == null || query.getSize() == null) {
            throw new ServiceException("基础业务校验异常:分页参数不能为空");
        }
    }

    /**
     * 查询接口 业务校验
     *
     * @param query
     * @throws ServiceException
     */
    public void checkQueryList(Q query) throws ServiceException {
        if (query == null) {
            throw new ServiceException("基础业务校验异常:空指针");
        }
    }

    /**
     * 更新接口 业务校验
     *
     * @param command
     * @throws ServiceException
     */
    public void checkEdit(A command) throws ServiceException {
        if (command == null) {
            throw new ServiceException("基础业务校验异常:空指针");
        }
    }

    /**
     * 根据ID查询接口 业务校验
     *
     * @param id
     * @throws ServiceException
     */
    public void checkQueryById(Long id) throws ServiceException {
        checkNullId(id);
    }

    /**
     * 查询接口(仅一条数据) 业务校验
     *
     * @param query
     * @throws ServiceException
     */
    public void checkQueryOne(Q query) throws ServiceException {
        if (query == null) {
            throw new ServiceException("基础业务校验异常:空指针");
        }
    }

    /**
     * 新增接口 业务校验
     *
     * @param command
     * @throws ServiceException
     */
    public void checkAdd(A command) throws ServiceException {
        if (command == null) {
            throw new ServiceException("基础业务校验异常:空指针");
        }
    }

    /**
     * 删除接口 业务校验
     *
     * @param id
     * @throws ServiceException
     */
    public void checkDelete(Long id) throws ServiceException {
        checkNullId(id);
    }

    /**
     * 批量删除接口 业务校验
     *
     * @param ids
     * @throws ServiceException
     */
    public void checkDeleteBatch(List<Long> ids) throws ServiceException {
        if (CollectionUtil.isEmpty(ids)) {
            throw new ServiceException("基础业务校验异常:ID不能为空");
        }
    }

    /**
     * 检查ID是否为空
     *
     * @param id
     * @throws ServiceException
     */
    protected void checkNullId(Long id) throws ServiceException {
        if (id == null) {
            throw new ServiceException("校验异常: 请选择数据进行处理");
        }
    }

    /**
     * 检查ID是否存在
     *
     * @param id
     * @throws ServiceException
     */
    protected void checkIdExist(Long id) throws ServiceException {
       this.checkNullId(id);
        if (repository.countById(id) == 0) {
            throw new ServiceException("校验异常: 数据不存在, 请刷新后重试");
        }
    }

    /**
     * 激活状态 业务校验
     *
     * @param ids
     * @param activation
     * @throws ServiceException
     */
    protected void checkEditActivation(List<Long> ids, Integer activation) throws ServiceException {
        if (CollectionUtil.isEmpty(ids)) {
            throw new ServiceException("校验异常: ID不能为空");
        }
        if (activation == null) {
            throw new ServiceException("校验异常: 激活状态不能为空");
        }
        if (!EnumUtil.checkCode(activation, ActivationEnum.values())) {
            throw new ServiceException("校验异常: 激活状态异常");
        }
        int count = repository.countByIds(ids);
        if (count != ids.size()) {
            throw new ServiceException("校验异常: 数据不存在, 请刷新后重试");
        }
    }

    @PostConstruct
    private void init() {
        this.getRepository();
    }

    /**
     * 获取数据访问对象
     *
     * @return
     */
    protected R getRepository() {
        if (this.repository == null) {
            Class<R> sampleObjectCallBack = this.getSuperClassGenricType(4);
            this.repository = this.applicationContext.getBean(sampleObjectCallBack);
        }
        return this.repository;
    }

    /**
     * 获取服务Bean类型
     *
     * @param index
     * @return
     */
    public Class<R> getSuperClassGenricType(int index) {
        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
        int count = type.getActualTypeArguments().length;
        if (count > 0) {
            this.repositoryClass = (Class) type.getActualTypeArguments()[index];
        }
        return this.repositoryClass;
    }

}
